package de.luh.slimpp

import com.google.inject.Inject
import de.luh.slimpp.slimPP.ClassDefinition
import de.luh.slimpp.slimPP.Member
import de.luh.slimpp.slimPP.Method
import de.luh.slimpp.slimPP.Model
import org.eclipse.xtext.junit4.InjectWith
import org.eclipse.xtext.junit4.XtextRunner
import org.eclipse.xtext.junit4.util.ParseHelper
import org.junit.Test
import org.junit.runner.RunWith

import static org.junit.Assert.*

@RunWith(typeof(XtextRunner))
@InjectWith(typeof(SlimPPInjectorProvider))
class ModelPreprocessorTest {

	@Inject extension ParseHelper<Model>

	@Test
	def testGetters() {
		val model = 'class C1   class a.b.C2{T=int}   c{d{ class C3 }}'.parse
		val preprocessor = new ModelPreprocessor()
		preprocessor.doPreprocessing(model)

		assertNotNull(preprocessor.getClass("C1"))
		assertEquals(preprocessor.getHeader("C1"), "\"C1.h\"")

		assertNotNull(preprocessor.getClass("a.b.C2"))
		assertEquals(preprocessor.getHeader("a.b.C2"), "\"a/b/C2.h\"")

		assertNotNull(preprocessor.getClass("c.d.C3"))
		assertEquals(preprocessor.getHeader("c.d.C3"), "\"c/d/C3.h\"")

		assertNotNull(preprocessor.getTypeDef("a.b.C2.T"))
		assertEquals(preprocessor.getHeader("a.b.C2.T"), "\"a/b/C2.h\"")
	}

	@Test
	def testResolveVisibility() {

		// set up the model from code and retrieve the relevant parts
		val model = 'class C { void method()   -int privateMethod()   int member }'.parse
		val classC = model.definitions.head as ClassDefinition
		val method = classC.defs.head as Method
		val privateMethod = classC.defs.get(1) as Method
		val member = classC.defs.get(2) as Member

		// without processing the visibilities that were not specified should be
		// null right now
		assertNull(method.getVisibility())
		assertNotNull(privateMethod.getVisibility())
		assertNull(member.getVisibility())

		// preprocess and make sure the visibilities were resolved correctly
		new ModelPreprocessor().doPreprocessing(model)
		assertTrue(method.getVisibility().isPublic())
		assertTrue(privateMethod.getVisibility().isPrivate())
		assertTrue(member.getVisibility().isPrivate())
	}
}
